#include <algorithm>
#include <initializer_list>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <string>
#include <type_traits>
#include <utility>

using ll = long long;
#define NVF(v)#v," : ",(v)

template<class ...Args>
std::string fmt(Args&&...args){
    std::ostringstream oss;
    (oss<<...<<std::forward<Args>(args));
    return std::string(oss.str());
}

template<class ...Args>
void print(Args&&...args){
    std::ostringstream oss;
    (oss<<...<<std::forward<Args>(args));
    std::cout<<oss.str();
}

// #define NDEBUG
#ifdef NDEBUG
    #define NDB_NOEXCEPT noexcept
#else
    #define NDB_NOEXCEPT
#endif

template<class T, ll _size>//size_t
class SafeArray{
    T arr[_size];
public:
    constexpr SafeArray()NDB_NOEXCEPT{};
    constexpr SafeArray(const std::initializer_list<T> init)NDB_NOEXCEPT:arr{}{
        #ifndef NDEBUG
            if(!std::is_constant_evaluated())[[unlikely]]{
                if(init.size()>_size){
                    throw std::runtime_error(fmt("std::initializer _size error when constructing SafeArray\n",
                                                "in ",__PRETTY_FUNCTION__," \n",
                                                "initialize_list should < ",_size,"\n"
                                                "but your initialize_list.size is ",init.size(),"\n"));
                }
            }
        #endif
        std::copy(init.begin(),init.end(),arr);
    }
    static constexpr ll size()noexcept{
        return _size;
    }
    constexpr T& operator[](const ll index)NDB_NOEXCEPT{
        #ifndef NDEBUG
            if(!std::is_constant_evaluated()){
                if(!(0<=index&&index<_size))[[unlikely]]{
                    throw std::runtime_error(fmt("in ",__PRETTY_FUNCTION__," error!\n",
                                                "0 <= index < ",_size,'\n',
                                                "but your index is : ",index,"\n"));
                }
            }
        #endif
        return arr[index];
    }
    constexpr const T& operator[](const ll index)const NDB_NOEXCEPT{
        #ifndef NDEBUG
            if(!std::is_constant_evaluated()){
                if(!(0<=index&&index<_size))[[unlikely]]{
                    throw std::runtime_error(fmt("in ",__PRETTY_FUNCTION__," error!\n",
                                                "0 <= index < ",_size,'\n',
                                                "but your index is :",index,"\n"));
                }
            }
        #endif
        return arr[index];
    }
};

int main(){
    // const int *const p = new int;
    // p = new int;

    constexpr SafeArray<ll, 5> arr{1,2,3,4,5};
    SafeArray<ll, 5> arr1{0,1,2,3,4};
    arr1[4]=5;
    arr[-1];
    print(NVF(arr[4]),'\n',
            NVF(arr[5]),'\n');
}